package com.alibaba.citrus.cr.sales.plan.facade.service;

import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcorder.model.dto.BaselineGetOrganizationByIds2Request;
import com.epoch.app.bcorder.model.dto.BaselineGetOrganizationByIds2Response;
import com.epoch.app.bcorder.model.dto.ScItemSDO;
import com.epoch.app.bcorder.model.dto.SearchScItemRequest;
import com.epoch.app.bcorder.model.dto.SearchWarehouseByOrgRequest;
import com.epoch.app.bcorder.model.dto.SearchWarehouseByOrgResponse;
import com.epoch.app.bcorder.model.dto.WarehouseInfo;
import com.epoch.app.bcorder.service.BaseDataService;
import com.epoch.app.bcorder.service.UnifiedInventoryService;
import com.epoch.app.crplatformenhance.api.customeraddressquery.service.CustomerAddressQueryService;
import com.epoch.app.crplatformenhance.api.customerquery.service.CustomerQueryService;
import com.epoch.app.crplatformenhance.api.organizationquery.dto.GetOrganizationsByOutCodesRequest;
import com.epoch.app.crplatformenhance.api.organizationquery.service.OrganizationQueryService;
import com.epoch.app.crplatformenhance.domain.customersalescope.dto.BatchQueryByCustomerCodesRequest;
import com.epoch.app.crplatformenhance.domain.customersalescope.model.CustomerSaleScope;
import com.epoch.app.crplatformenhance.domain.customersalescope.service.CustomerSaleScopeService;
import com.epoch.app.crplatformenhance.dto.request.CustomerAddressBatchRequest;
import com.epoch.app.crplatformenhance.dto.request.CustomerBatchRequest;
import com.epoch.app.crplatformenhance.model.dto.CustomerAddressIndex;
import com.epoch.app.crplatformenhance.opecustomeraddressindex.dto.PageQueryCustomerAddressRequest;
import com.epoch.app.crplatformenhance.opecustomeraddressindex.dto.PageQueryCustomerAddressResponse;
import com.epoch.app.crplatformenhance.opecustomeraddressindex.service.OpeCustomerAddressIndexService;
import com.epoch.app.crplatformenhance.sdo.CustomerAddressSDO;
import com.epoch.app.crplatformenhance.sdo.CustomerSDO;
import com.epoch.app.crplatformenhance.sdo.OrganizationSDO;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author luyi
 * @date 2021/11/8 9:40 下午
 */
@Component
public class SalesPlanOutCommonService {

    private final static Log log = Log.getLogger(SalesPlanOutCommonService.class);

    @Resource
    private BaseDataService baseDataService;

    @Resource
    private UnifiedInventoryService unifiedInventoryService;

    @Autowired(required = false)
    private CustomerAddressQueryService customerAddressQueryService;

    @Autowired(required = false)
    private OrganizationQueryService organizationQueryService;

    @Autowired(required = false)
    private CustomerQueryService customerService;

    @Resource
    private OpeCustomerAddressIndexService opeCustomerAddressIndexService;

    @Resource
    private CustomerSaleScopeService customerSaleScopeService;

    /**
     * 根据销售组织查询共享仓
     *
     * @param saleOrgId
     */
    public List<WarehouseInfo> getSharedWarehouseListBySaleOrgId(String saleOrgId) {
        SearchWarehouseByOrgRequest searchWarehouseByOrgRequest = new SearchWarehouseByOrgRequest();
        searchWarehouseByOrgRequest.setSaleOrgIdList(Lists.newArrayList(saleOrgId));
        searchWarehouseByOrgRequest.setModel(3);//1是仓库档案，3是逻辑仓，6门店
        searchWarehouseByOrgRequest.setTypeList(Lists.newArrayList(2));//2共享仓，3销售单元仓 5工厂仓
        searchWarehouseByOrgRequest.setStatus(1);
        searchWarehouseByOrgRequest.setStart(0);
        searchWarehouseByOrgRequest.setLimit("1000");
        SearchWarehouseByOrgResponse response = unifiedInventoryService.searchWarehouseByOrg(searchWarehouseByOrgRequest);
        if (Objects.isNull(response) || CollectionUtils.isEmpty(response.getResult())) {
            log.error("SalesPlanOutCommonService.getCargoZoneMapBySaleOrgId not found request:"+saleOrgId);
            return null;
        }
        return response.getResult();
    }


    /**
     * 根据货品外部编码查询货品信息
     *
     * @param scItemSet
     * @return
     */
    public Map<String, ScItemSDO> getScItemMapByOutId(Set<String> scItemSet) {
        if (CollectionUtils.isEmpty(scItemSet)) {
            return null;
        }
        //批量查货品，换取scItemId
        SearchScItemRequest searchScItemRequest = new SearchScItemRequest();
        JSONObject searchReqDTO = new JSONObject();
        searchReqDTO.put("outerIdList", scItemSet);
        searchReqDTO.put("businessType","11");//业态常温
        searchReqDTO.put("type",0);//非组合货品
        searchScItemRequest.setSearchReqDTO(searchReqDTO);
        //原来最多只能查到20条
        searchScItemRequest.setPageSize(scItemSet.size());
        Result<List<ScItemSDO>> scItemResult = baseDataService.searchScItem(searchScItemRequest);
        if (!SalesPlanCommonService.resultCheck(scItemResult, null)) {
            log.error("SalesPlanOutCommonService.getScItemMapByOutId not found request:"+scItemSet);
            return null;
        }
        return scItemResult.getResult().stream().collect(Collectors.toMap(ScItemSDO::getOuterId, a -> a, (a, b) -> a));
    }

    /**
     * 根据客户地址编码查询地址信息
     *
     * @param customerAddressSet
     * @return
     */
    @Deprecated
    public Map<String, CustomerAddressSDO> getCustomerAddressMap(Set<String> customerAddressSet) {
        if (CollectionUtils.isEmpty(customerAddressSet)) {
            return null;
        }
        CustomerAddressBatchRequest customerAddressBatchRequest = new CustomerAddressBatchRequest();
        customerAddressBatchRequest.setAddressCodes(Lists.newArrayList(customerAddressSet));
        Result<List<CustomerAddressSDO>> customerAddressResult = customerAddressQueryService.batchQueryCustomerAddress(customerAddressBatchRequest);
        if (!SalesPlanCommonService.resultCheck(customerAddressResult, null)) {
            return null;
        }
        return customerAddressResult.getResult().stream().collect(Collectors.toMap(CustomerAddressSDO::getAddressCode, a -> a, (a, b) -> a));
    }

    /**
     * 根据客户地址编码查询地址信息 联合key
     *
     * @param customerAddressSet
     * @return
     */
    public Map<String, CustomerAddressSDO> getCustomerAddressMapCombineKey(Set<String> customerAddressSet) {
        if (CollectionUtils.isEmpty(customerAddressSet)) {
            return null;
        }
        CustomerAddressBatchRequest customerAddressBatchRequest = new CustomerAddressBatchRequest();
        customerAddressBatchRequest.setAddressCodes(Lists.newArrayList(customerAddressSet));
        Result<List<CustomerAddressSDO>> customerAddressResult = customerAddressQueryService.batchQueryCustomerAddress(customerAddressBatchRequest);
        if (!SalesPlanCommonService.resultCheck(customerAddressResult, null)) {
            return null;
        }
        return customerAddressResult.getResult().stream().collect(Collectors.toMap(c -> c.getCustomerCode() + c.getAddressCode(), a -> a, (a, b) -> a));
    }

    /**
     * 根据客户地址编码查询客户信息
     *
     * @param customerAddressSet
     * @return
     */
    public Map<String, CustomerSDO> getCustomerMap(Set<String> customerAddressSet) {
        if (CollectionUtils.isEmpty(customerAddressSet)) {
            return null;
        }
        CustomerBatchRequest customerBatchRequest = new CustomerBatchRequest();
        customerBatchRequest.setCodes(Lists.newArrayList(customerAddressSet));
        Result<List<CustomerSDO>> result = customerService.batchQueryCustomer(customerBatchRequest);
        if (!SalesPlanCommonService.resultCheck(result, null)) {
            return null;
        }
        return result.getResult().stream().collect(Collectors.toMap(CustomerSDO::getCode, a -> a));
    }

    /**
     * 根据客户编码查询客户售达方信息
     * @param customerCodeSet
     * @return
     */
    public Map<String, CustomerSaleScope> getCustomerSaleScopeMap(Set<String> customerCodeSet) {
        if (CollectionUtils.isEmpty(customerCodeSet)) {
            return Maps.newHashMap();
        }
        BatchQueryByCustomerCodesRequest batchQueryByCustomerCodesRequest = new BatchQueryByCustomerCodesRequest();
        batchQueryByCustomerCodesRequest.setCustomerCodes(Lists.newArrayList(customerCodeSet) );
        Result<List<CustomerSaleScope>> result = customerSaleScopeService.batchQueryByCustomerCodes(batchQueryByCustomerCodesRequest);
        if (!SalesPlanCommonService.resultCheck(result, null)) {
            return Maps.newHashMap();
        }
        return result.getResult().stream().collect(Collectors.toMap(CustomerSaleScope::getCustomerCode, a -> a));
    }

    /**
     * 更具组织外部编码查询组织
     *
     * @param outCodeSet
     * @return
     */
    public Map<String, OrganizationSDO> getOrganizationMapByOutCode(Set<String> outCodeSet) {
        if (CollectionUtils.isEmpty(outCodeSet)) {
            return null;
        }
        GetOrganizationsByOutCodesRequest request = new GetOrganizationsByOutCodesRequest();
        request.setOutCodes(Lists.newArrayList(outCodeSet));
        Result<List<OrganizationSDO>> organizationsByOutCodes = organizationQueryService.getOrganizationsByOutCodes(request);
        if (!SalesPlanCommonService.resultCheck(organizationsByOutCodes, null)) {
            log.error("SalesPlanOutCommonService.getOrganizationMapByOutCode not found request:"+outCodeSet);
            return null;
        }
        return organizationsByOutCodes.getResult().stream().collect(Collectors.toMap(OrganizationSDO::getOutCode, o -> o,(a,b)->a));
    }

    /**
     * 批量查询组织
     *
     * @param orgIdsSet
     * @return 外部编码还是内部编码(true 外部, false 内部)
     * @return
     */
    public Map<String, com.epoch.app.bcorder.model.dto.OrganizationSDO> getOrganizationMapByIds(Set<String> orgIdsSet, Boolean outOrOrgId) {
        if (CollectionUtils.isEmpty(orgIdsSet)) {
            return null;
        }
        BaselineGetOrganizationByIds2Request request = new BaselineGetOrganizationByIds2Request();
        request.setIds(Lists.newArrayList(orgIdsSet));
        request.setStatus(1);
        BaselineGetOrganizationByIds2Response byIds2Response = baseDataService.baselineGetOrganizationByIds2(request);
        if (Objects.isNull(byIds2Response) || CollectionUtils.isEmpty(byIds2Response.getResult())) {
            log.error("SalesPlanOutCommonService.getOrganizationMapByIds not found request:"+orgIdsSet);
            return null;
        }

        if (outOrOrgId) {
            return byIds2Response.getResult().stream().collect(Collectors.toMap(com.epoch.app.bcorder.model.dto.OrganizationSDO::getCode, a -> a, (a, b) -> a));
        } else {
            return byIds2Response.getResult().stream().collect(Collectors.toMap(com.epoch.app.bcorder.model.dto.OrganizationSDO::getId, a -> a, (a, b) -> a));
        }
    }

    /**
     * 根据货品id查询货品信息
     *
     * @param scItemIdsSet
     * @return 外部编码还是内部编码(true 外部, false 内部)
     */
    public Map<String, ScItemSDO> getScItemMapByIds(Set<String> scItemIdsSet, Boolean outOrScItemId) {
        if (CollectionUtils.isEmpty(scItemIdsSet)) {
            return null;
        }
        //查询货品
        SearchScItemRequest searchScItemRequest = new SearchScItemRequest();
        JSONObject searchReqDTO = new JSONObject();
        searchReqDTO.put("scItemIds", scItemIdsSet);
        searchReqDTO.put("statusList", Lists.newArrayList(1,-1));
        searchScItemRequest.setSearchReqDTO(searchReqDTO);
        searchScItemRequest.setPageSize(scItemIdsSet.size());
        Result<List<ScItemSDO>> scItemResult = baseDataService.searchScItem(searchScItemRequest);
        if (!SalesPlanCommonService.resultCheck(scItemResult, null)) {
            log.error("SalesPlanOutCommonService.getScItemMapByIds not found request:" + scItemIdsSet);
            return null;
        }
        if (outOrScItemId) {
            return scItemResult.getResult().stream().collect(Collectors.toMap(ScItemSDO::getOuterId, a -> a, (a, b) -> a));
        } else {
            return scItemResult.getResult().stream().collect(Collectors.toMap(ScItemSDO::getScItemId, a -> a, (a, b) -> a));
        }
    }

    /**
     * 五键唯一查询客户地址
     * @param customerAddressSet
     * @param customerSet
     * @param organizationIdList
     * @param channelCodeSet
     * @param itemGroupSet
     * @return
     */
    public Map<String, CustomerAddressIndex> getCustomerAddressByFive(Set<String> customerAddressSet,
                                                                        Set<String> customerSet,
                                                                        Set<String> organizationIdList,
                                                                        Set<String> channelCodeSet,
                                                                        Set<String> itemGroupSet){
        if (CollectionUtils.isEmpty(customerAddressSet)) {
            return Maps.newHashMap();
        }

        PageQueryCustomerAddressRequest customerAddressRequest = new PageQueryCustomerAddressRequest();
        if (CollectionUtils.isNotEmpty(organizationIdList)){
            customerAddressRequest.setOrgSaleOrganizationCodeList(Lists.newArrayList(organizationIdList));
        }
        if (CollectionUtils.isNotEmpty(channelCodeSet)){
            customerAddressRequest.setChannelCodeList(Lists.newArrayList(channelCodeSet));
        }
        if (CollectionUtils.isNotEmpty(customerSet)){
            customerAddressRequest.setCustomerCodeList(Lists.newArrayList(customerSet));
        }
        if (CollectionUtils.isNotEmpty(customerAddressSet)){
            customerAddressRequest.setAddressCodeList(Lists.newArrayList(customerAddressSet));
        }
        if (CollectionUtils.isNotEmpty(itemGroupSet)){
            customerAddressRequest.setItemGroupList(Lists.newArrayList(itemGroupSet));
        }
        customerAddressRequest.setStart(0);
        customerAddressRequest.setLimit(1000);
        // 1:启用 2:禁用
        customerAddressRequest.setStatus(1);
        PageQueryCustomerAddressResponse customerAddressResponse = opeCustomerAddressIndexService.pageQueryCustomerAddress(customerAddressRequest);
        if (customerAddressResponse == null || CollectionUtils.isEmpty(customerAddressResponse.getResult())){
            log.error("SalesPlanOutCommonService.getCustomerAddressByFive not found");
            return null;
        }
        return customerAddressResponse.getResult().stream().
                collect(Collectors.toMap(address->{
                    // 客户编码 + 客户地址编码 + 销售组织编码（ID） + 业务渠道编码 + 货品组
                    StringBuilder builder = new StringBuilder();
                    if (CollectionUtils.isNotEmpty(customerSet)){
                        builder.append(address.getCustomerCode());
                    }
                    if (CollectionUtils.isNotEmpty(customerAddressSet)){
                        builder.append(address.getAddressCode());
                    }
                    if (CollectionUtils.isNotEmpty(organizationIdList)){
                        builder.append(address.getOrgSaleOrganizationCode());
                    }
                    if (CollectionUtils.isNotEmpty(channelCodeSet)){
                        builder.append(address.getChannelCode());
                    }
                    if (CollectionUtils.isNotEmpty(itemGroupSet)){
                        builder.append(address.getItemGroup());
                    }
                    return builder.toString();
                },a->a,(a,b)->a));
    }

    /**
     * 根据货品外部编码查询货品信息(支持模糊搜索)
     *
     * @param outerId
     * @return
     */
    public List<ScItemSDO> getScItemListByOutId(String outerId) {
        log.info("salesPlanOutCommonService.getScItemListByOutId.outerId={}", outerId);
        if (StringUtils.isEmpty(outerId)) {
            return null;
        }
        SearchScItemRequest searchScItemRequest = new SearchScItemRequest();
        JSONObject searchReqDTO = new JSONObject();
        searchReqDTO.put("outerId", outerId);
        searchScItemRequest.setSearchReqDTO(searchReqDTO);
        log.info("salesPlanOutCommonService.getScItemListByOutId.request={}", JSONObject.toJSONString(searchScItemRequest));
        Result<List<ScItemSDO>> scItemResult = baseDataService.searchScItem(searchScItemRequest);
        if (!SalesPlanCommonService.resultCheck(scItemResult, null)) {
            log.error("SalesPlanOutCommonService.getScItemMapByOutId not found request:" + JSONObject.toJSONString(searchScItemRequest));
            return null;
        }
        return scItemResult.getResult();
    }
}
